package com.autumn.platform.dao.schema.script.original;

import java.util.ArrayList;
import java.util.List;

import org.apache.ibatis.builder.BuilderException;
import org.apache.ibatis.parsing.XNode;
import org.apache.ibatis.scripting.xmltags.ChooseSqlNode;
import org.apache.ibatis.scripting.xmltags.SqlNode;
import org.apache.ibatis.session.Configuration;

import com.autumn.platform.dao.HandlerRegister;
import com.autumn.platform.dao.schema.script.IScriptHandler;

public class ChooseScriptHandler implements IScriptHandler {

    @Override
    public void handleScriptNode(Configuration configuration, XNode node, List<SqlNode> targetContents) {
        List<SqlNode> whenSqlNodes = new ArrayList<SqlNode>();
        List<SqlNode> otherwiseSqlNodes = new ArrayList<SqlNode>();
        handleWhenOtherwiseNodes(configuration, node, whenSqlNodes, otherwiseSqlNodes);
        SqlNode defaultSqlNode = getDefaultSqlNode(otherwiseSqlNodes);
        ChooseSqlNode chooseSqlNode = new ChooseSqlNode(whenSqlNodes, defaultSqlNode);
        targetContents.add(chooseSqlNode);
    }

    private void handleWhenOtherwiseNodes(Configuration configuration, XNode chooseSqlNode, List<SqlNode> ifSqlNodes,
            List<SqlNode> defaultSqlNodes) {
        List<XNode> children = chooseSqlNode.getChildren();
        for (XNode child : children) {
            IScriptHandler handler = HandlerRegister.getHandlerRegistry().getScriptHandler(child.getNode());
            if (handler instanceof IfScriptHandler) {
                handler.handleScriptNode(configuration, child, ifSqlNodes);
            } else if (handler instanceof OtherwiseScriptHandler) {
                handler.handleScriptNode(configuration, child, defaultSqlNodes);
            }
        }
    }

    private SqlNode getDefaultSqlNode(List<SqlNode> defaultSqlNodes) {
        SqlNode defaultSqlNode = null;
        if (defaultSqlNodes.size() == 1) {
            defaultSqlNode = defaultSqlNodes.get(0);
        } else if (defaultSqlNodes.size() > 1) {
            throw new BuilderException("Too many default (otherwise) elements in choose statement.");
        }
        return defaultSqlNode;
    }
}
